package gat.application.backgroundUser.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.bitsun.core.common.exception.AppException;
import com.bitsun.core.common.exception.ErrorCode;
import com.bitsun.core.common.persistence.BasePService;
import com.bitsun.core.common.persistence.IPService;
import com.bitsun.core.common.persistence.Pager;
import com.bitsun.core.common.persistence.QueryParamUtils;
import com.google.common.base.CaseFormat;
import gat.application.backgroundUser.RolePermissionsService;
import gat.application.backgroundUser.RoleService;
import gat.convertor.backgroundUser.RolePermissionsReqDtoConvertor;
import gat.convertor.backgroundUser.RolePermissionsResDtoConvertor;
import gat.dto.req.backgroundUser.RolePermissionsReqDto;
import gat.dto.res.backgroundUser.RolePermissionsResDto;
import gat.dto.res.backgroundUser.RoleResDto;
import gat.infrastructure.persistence.dao.backgroundUser.RolePermissionsMapper;
import gat.infrastructure.persistence.po.backgroundUser.RolePermissionsPo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.math.NumberUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 示例表，应用（业务编排）层实现
 * @author: tmac
 * @email: tmac
 */
@Slf4j
@Service("rolePermissionsAppService")
@Transactional(rollbackFor = Exception.class)
public class RolePermissionsServiceImpl implements RolePermissionsService {

    @Autowired
    private RolePermissionsReqDtoConvertor rolePermissionsReqDtoConvertor;

    @Autowired
    private RolePermissionsResDtoConvertor rolePermissionsResDtoConvertor;

    @Autowired
    private RoleService roleService;

    private IPService<RolePermissionsPo> permissionsRolePoService;

    @SuppressWarnings("SpringJavaAutowiringInspection")
    public RolePermissionsServiceImpl(RolePermissionsMapper permissionsRoleMapper) {
        this.permissionsRolePoService = new BasePService(permissionsRoleMapper);
    }


    @Override
    public List<Long> getByRoleId(List<Long> roleIds) {
        QueryWrapper<RolePermissionsPo> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().in(RolePermissionsPo::getRoleId,roleIds);
        List<RolePermissionsPo> list = permissionsRolePoService.list(queryWrapper);
        //将获取的id进行转换
        List<Long> collect = list.stream().map(RolePermissionsPo::getPermissionId).collect(Collectors.toList());
        return collect;
    }

    @Override
    public List<Long> selectPermission(Long roleId) {
        QueryWrapper<RolePermissionsPo> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(RolePermissionsPo::getRoleId,roleId);
        List<RolePermissionsPo> list = permissionsRolePoService.list(queryWrapper);
        //将获取的id进行转换
        List<Long> collect = list.stream().map(RolePermissionsPo::getPermissionId).collect(Collectors.toList());
        return collect;
    }

    @Override
    public List<RolePermissionsResDto> save(RolePermissionsReqDto reqDto) {
        //查看当前角色是否为系统角色
        RoleResDto roleResDto = roleService.selectOne(reqDto.getRoleId());
//        if (UserRoleTypeEnum.SYSTEM_ROLE.getValue().equals(roleResDto.getType())){
//            //系统角色无法进行其他操作
//            throw  new AppException(UserExceptionEnums.ROLE_SYSTEM_IS.getMsg());
//        }
        QueryWrapper<RolePermissionsPo> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(RolePermissionsPo::getRoleId,reqDto.getRoleId());
        List<RolePermissionsPo> list = permissionsRolePoService.list(queryWrapper);
        if (CollectionUtil.isNotEmpty(list)){
            //存在，则先删除角色权限，在进行新增
            permissionsRolePoService.remove(queryWrapper);
        }
        List<Long> permissionsId = reqDto.getPermissionIdList();
        ArrayList<RolePermissionsPo> rolePermissionsPos = new ArrayList<>();
        permissionsId.forEach(l->{
            RolePermissionsPo po = new RolePermissionsPo();
            po.setRoleId(reqDto.getRoleId());
            po.setPermissionId(l);
            rolePermissionsPos.add(po);
        });
        permissionsRolePoService.saveBatch(rolePermissionsPos);
        List<RolePermissionsResDto> resDtos = rolePermissionsResDtoConvertor.poList2DtoList(rolePermissionsPos);

        return resDtos;
    }

    @Override
    public boolean deleteByIds(String ids) {
        try {
            List<Long> idLongList =
            Arrays.asList(ids.split(",")).stream().map(s -> NumberUtils.createLong(s.trim())).collect(Collectors.toList());
            return permissionsRolePoService.removeByIds(idLongList);
        } catch (Exception e) {
            throw new AppException("参数错误：" + ids, ErrorCode.pc("417"), e);
        }
     }

    @Override
    public Pager<RolePermissionsResDto> doPager(Map<String, Object> params) {
        Pager<RolePermissionsPo> poPager = permissionsRolePoService.queryPage(params, RolePermissionsPo.class);
        Pager<RolePermissionsResDto> resDtoPager = rolePermissionsResDtoConvertor.convertPoPager2ResDtoPager(poPager);
        return resDtoPager;
    }

    @Override
    public RolePermissionsResDto selectOne(Long id) {
        RolePermissionsPo po = permissionsRolePoService.getById(id);
        RolePermissionsResDto resDto = rolePermissionsResDtoConvertor.po2Dto(po);
        return resDto;
    }

    @Override
    public RolePermissionsResDto selectOne(Map<String, Object> params) {
        QueryWrapper queryWrapper = QueryParamUtils.queryWrapper4eq(RolePermissionsPo::new, params);
        queryWrapper.last(" limit 1");
        RolePermissionsPo po = permissionsRolePoService.getOne(queryWrapper);
        RolePermissionsResDto resDto = rolePermissionsResDtoConvertor.po2Dto(po);
        return resDto;
    }

    @Override
    public boolean updateProps(Long id, Map<String, Object> params) {
        UpdateWrapper<RolePermissionsPo> updateWrapper = QueryParamUtils.updateWrapper4Map(RolePermissionsPo::new, id, params);
        return permissionsRolePoService.update(new RolePermissionsPo(), updateWrapper);
        }

    @Override
    public boolean updateProps(Long id, RolePermissionsReqDto reqDto) {
        RolePermissionsPo po = rolePermissionsReqDtoConvertor.dto2Po(reqDto);
        po.setId(id);
        return permissionsRolePoService.updateById(po);
    }


    @Override
    public boolean updateAllProps(Long id, RolePermissionsReqDto reqDto) {
        UpdateWrapper<RolePermissionsPo> updateWrapper = Wrappers.update();
        updateWrapper.eq("id", id);
        Field[] fields = RolePermissionsReqDto.class.getDeclaredFields();
        Arrays.stream(fields).filter(f -> !Modifier.isStatic(f.getModifiers())).forEach(field -> {
        try {
        PropertyDescriptor propertyDescriptor = new PropertyDescriptor(field.getName(), RolePermissionsReqDto.class);
        Method getMethod = propertyDescriptor.getReadMethod();
        String fileNameCamel = getMethod.getName().substring(3);
        String fileNameUnderline = CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, fileNameCamel);
        updateWrapper.set(fileNameUnderline, getMethod.invoke(reqDto));
        } catch (Exception ex) {
        log.warn("属性不存在get方法："+field.getName(),ex);
        }
        });
        return permissionsRolePoService.update(new RolePermissionsPo(), updateWrapper);
    }

}